/**
 * Copyright (c) 2018-2022, BookOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: Multiboot2 start file
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2021-9-17      JasonHu           Init
 * 2022-06-03     JasonHu           Add framebuffer support
 */

#define __ASSEMBLY__
#include <base/defines.h>
#include <nx_configure.h>
#include <multiboot2.h>

# the NX_USize of bootStack is 16KB
#define BOOT_STACK_SIZE 0x4000

.code32

.section .text.start
.extern __NX_EarlyMain
.extern NX_HalBootSetting

NX_FUNC(Start)
NX_FUNC(_start)
    jmp MultibootEntry

.align 8
MultibootHeader:
    .long MULTIBOOT2_HEADER_MAGIC                  # magic number (multiboot 2)
    .long MULTIBOOT_ARCHITECTURE_I386              # architecture 0 (protected mode i386)
    .long MultibootHeaderEnd - MultibootHeader  # header length
    # checksum
    .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (MultibootHeaderEnd - MultibootHeader))
    # insert optional multiboot tags here

#ifdef CONFIG_NX_HARDWARE_VBE
    .align 8
    TagFramebuffer:
        .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long  TagFramebufferEnd - TagFramebuffer
        .long  CONFIG_NX_HARDWARE_VBE_WIDTH    # screen width
        .long  CONFIG_NX_HARDWARE_VBE_HEIGHT   # screen height
        .long  CONFIG_NX_HARDWARE_VBE_BPP      # bit per pixel
    TagFramebufferEnd:
#endif /* CONFIG_NX_HARDWARE_VBE */

    # required end tag
    .align 8
    .short MULTIBOOT_HEADER_TAG_END # type
    .short 0                        # flags
    .long  8                        # NX_USize
MultibootHeaderEnd:
MultibootEntry:
    # initialize the bootStack pointer
    movl $(bootStack + BOOT_STACK_SIZE), %esp

    # reset EFLAGS
    pushl $0
    popf
    
    # push the pointer to the Multiboot information structure
    pushl %ebx
    # push the magic value
    pushl %eax
    
    call NX_HalBootSetting
    cmpl $-1, %eax
    je BootSetupFail

    add $8, %esp

    # call os main
    push $0 # coreId == 0
    call __NX_EarlyMain
    add $4, %esp
    jmp MultibootHlt

BootSetupFail:
    # print "Error!" in protected mode
    movl $0xcf72cf45, 0xb8000
    movl $0xcf6fcf72, 0xb8004
    movl $0xcf21cf72, 0xb8008

MultibootHlt:
    hlt
    jmp MultibootHlt

NX_ENDFUNC(Start)
NX_ENDFUNC(_start)

    .comm bootStack, BOOT_STACK_SIZE
